package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.client.LogininfoClient;
import cn.itsource.ymcc.domain.*;
import cn.itsource.ymcc.dto.RegDto;
import cn.itsource.ymcc.mapper.UserBaseInfoMapper;
import cn.itsource.ymcc.mapper.UserGrowLogMapper;
import cn.itsource.ymcc.mapper.UserMapper;
import cn.itsource.ymcc.mapper.UserRealInfoMapper;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.IUserService;
import cn.itsource.ymcc.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 会员登录账号 服务实现类
 * </p>
 *
 * @author whale.chen
 * @since 2023-02-26
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserBaseInfoMapper userBaseInfoMapper;
    @Autowired
    private UserRealInfoMapper userRealInfoMapper;
    @Autowired
    private UserGrowLogMapper userGrowLogMapper;
    @Autowired
    private LogininfoClient logininfoClient;

    /**
     * 前台用户注册
     * @param regDto
     * @return
     */
    @GlobalTransactional(rollbackFor = Exception.class)
    @Override
    public void register(RegDto regDto) {
        //1.手机号必须是未注册的
        User user = baseMapper.selectOne(new QueryWrapper<User>()
                .eq("phone", regDto.getMobile()));
        AssertUtil.isTrue(user == null, "该手机号已被注册！");

        //2.校验短信验证码
        AssertUtil.isTrue(redisTemplate.hasKey(regDto.getMobile()), "短信验证码已过期！");
        AssertUtil.isTrue(regDto.getSmsCode().equals(redisTemplate.opsForValue().get(regDto.getMobile())), "短信验证码错误！");

        //3.openfeign调用认证中心接口，保存登录账户信息
        Logininfo logininfo = new Logininfo()
                .setUsername(regDto.getMobile())
                .setPassword(new BCryptPasswordEncoder().encode(regDto.getPassword()))
                .setType(1);
        JsonResult jsonResult = logininfoClient.saveOrUpdate(logininfo);
        AssertUtil.isTrue(jsonResult.getSuccess(), jsonResult.getMessage());
        //使用openfeign调用三方接口：三方接口返回的值是Long，但经过openfeign后，变成了Integer
        Long logininfoid = ((Integer) jsonResult.getData()).longValue();

        //4.保存数据
        user = new User()
            .setPhone(regDto.getMobile())
            .setNickName(regDto.getMobile())
            .setLoginId(logininfoid);
        //由于单表操作无需写SQL，mybatisplus不确定你到底需不需要返回主键，只要insert数据都会返回主键
        baseMapper.insert(user);

        //用户的基本资料
        UserBaseInfo userBaseInfo = new UserBaseInfo()
                .setRegChannel(regDto.getRegChannel())
                .setUserId(user.getId());
        userBaseInfoMapper.insert(userBaseInfo);

        //用户实名认证信息
        UserRealInfo userRealInfo = new UserRealInfo()
                .setUserId(user.getId());
        userRealInfoMapper.insert(userRealInfo);

        //注册送积分：建议使用properties文件或者一张表来维护每个操作送多少积分
        UserGrowLog userGrowLog = new UserGrowLog()
                .setUserId(user.getId())
                .setFromReason("新用户注册")
                .setScore(50);
        userGrowLogMapper.insert(userGrowLog);

        int i = 2/0;

    }
}
